
#include <BScript>
#include "IClassArray.h"
#include "IClassSet.h"

using namespace BWE;

ClassSet::ClassSet() : BClass("set<T>")
{
	this->insertMethod("set<T>()", &ClassSet::create);
	this->insertMethod("set<T>(const set<T>&)", &ClassSet::create_other);
	this->insertMethod("~set<T>()", &ClassSet::release);

	this->insertMethod("int size() const", &ClassSet::size);
	this->insertMethod("int capacity() const", &ClassSet::capacity);

	this->insertMethod("bool empty() const", &ClassSet::empty);
	this->insertMethod("void reset()", &ClassSet::reset);
	this->insertMethod("void clear()", &ClassSet::clear);
	this->insertMethod("bool relax()", &ClassSet::relax);

	this->insertMethod("bool reserve()", &ClassSet::reserve);
	this->insertMethod("bool check(int) const", &ClassSet::check);
	this->insertMethod("bool contain(T) const", &ClassSet::contain);
	this->insertMethod("int find(const T&) const", &ClassSet::find);

	this->insertMethod("T& first()", &ClassSet::first);
	this->insertMethod("const T& first() const", &ClassSet::first_const);

	this->insertMethod("T& middle()", &ClassSet::middle);
	this->insertMethod("const T& middle() const", &ClassSet::middle_const);

	this->insertMethod("T& last()", &ClassSet::last);
	this->insertMethod("const T& last() const", &ClassSet::last_const);

	this->insertMethod("T& min()", &ClassSet::min);
	this->insertMethod("const T& min() const", &ClassSet::min_const);

	this->insertMethod("T& max()", &ClassSet::max);
	this->insertMethod("const T& max() const", &ClassSet::max_const);

	this->insertMethod("T& at(int)", &ClassSet::at_index);
	this->insertMethod("const T& at(int) const", &ClassSet::at_index_const);

	this->insertMethod("int insert(const T&)", &ClassSet::insert_value);
	this->insertMethod("int insert(const set<T>&)", &ClassSet::insert_other);

	this->insertMethod("bool remove(const T&)", &ClassSet::remove_value);
	this->insertMethod("int remove(const set<T>&)", &ClassSet::remove_other);
	this->insertMethod("int remove(int,int)", &ClassSet::remove_pos_size);
	this->insertMethod("int remove(const array<T>&)", &ClassSet::remove_array_size);

	this->insertMethod("int < (const T&) const", &ClassSet::less);
	this->insertMethod("int <= (const T&) const", &ClassSet::lessEqual);

	this->insertMethod("int > (const T&) const", &ClassSet::greater);
	this->insertMethod("int >= (const T&) const", &ClassSet::greaterEqual);

	this->insertMethod("void = (const set<T>&)", &ClassSet::operator_assign);

	this->insertMethod(" T& ()(int index)", &ClassSet::operator_bracket);
	this->insertMethod(" const T& ()(int index) const", &ClassSet::operator_bracket_const);

	this->insertMethod(" T& [](int index)", &ClassSet::operator_square_bracket);
	this->insertMethod(" const T& [](int index) const", &ClassSet::operator_square_bracket_const);

}

BClass* ClassSet::clone() const
{
	ClassSet* cls = new ClassSet();
	cls->copy(this);
	return cls;
}

void ClassSet::create(int argc, BValue* argv)
{
	this->setAsset(new BValueSet());
}
void ClassSet::create_other(int argc, BValue* argv)
{
	BValueSet* set = new BValueSet();
	if (ClassSet* otherSet = argv[1])
	{
		const BValueSet& other = otherSet->asset();
		*set = other;
	}
	this->setAsset(set);
}
void ClassSet::release(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	set.clear();
}

void ClassSet::size(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.size();
}
void ClassSet::capacity(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.capacity();
}

void ClassSet::empty(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.empty();
}
void ClassSet::reset(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	set.reset();
}
void ClassSet::clear(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	set.clear();
}
void ClassSet::relax(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.relax();
}

void ClassSet::reserve(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	int size = argv[1];
	argv[0] = set.reserve(size);
}
void ClassSet::check(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set.check(index);
}
void ClassSet::contain(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	const BValue& value = argv[1];
	argv[0] = set.contain(value);
}
void ClassSet::find(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	const BValue& value = argv[1];
	argv[0] = set.find(value);
}

void ClassSet::first(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.first();
}
void ClassSet::first_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.first();
}

void ClassSet::middle(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.middle();
}
void ClassSet::middle_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.middle();
}

void ClassSet::last(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.last();
}
void ClassSet::last_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.last();
}

void ClassSet::min(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.min();
}
void ClassSet::min_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.min();
}

void ClassSet::max(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	argv[0] = set.max();
}
void ClassSet::max_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	argv[0] = set.max();
}

void ClassSet::at_index(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set.at(index);
}
void ClassSet::at_index_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set.at(index);
}

void ClassSet::insert_value(int argc, BValue * argv)
{
	BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set.insert(value);
}
void ClassSet::insert_other(int argc, BValue * argv)
{
	BValueSet& set = this->asset();
	if (ClassSet* otherSet = argv[1])
	{
		const BValueSet& other = otherSet->asset();
		argv[0] = set.insert(other);
	}
	else
	{
		argv[0] = 0;
	}
}

void ClassSet::remove_value(int argc, BValue * argv)
{
	BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set.remove(value);
}
void ClassSet::remove_other(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	if (ClassSet* otherSet = argv[1])
	{
		const BValueSet& other = argv[1];
		argv[0] = set.remove(other);
	}
	else
	{
		argv[0] = false;
	}
}
void ClassSet::remove_pos_size(int argc, BValue * argv)
{
	BValueSet& set = this->asset();
	int pos = argv[1];
	int count = argv[2];
	argv[0] = set.remove(pos, count);
}
void ClassSet::remove_array_size(int argc, BValue * argv)
{
	BValueSet& set = this->asset();
	if (ClassArray* arrayObject = argv[1])
	{
		int count = 0;
		const BValueArray& array = arrayObject->asset();
		for (int i = 0; i < array.size(); i++)
		{
			if (set.remove(array[i]))
				count++;
		}
		argv[0] = count;
	}
	else
	{
		argv[0] = 0;
	}
}

void ClassSet::less(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set < value;
}
void ClassSet::lessEqual(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set <= value;
}

void ClassSet::greater(int argc, BValue * argv)
{
	const BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set > value;
}
void ClassSet::greaterEqual(int argc, BValue * argv)
{
	const BValueSet& set = this->asset();
	const BValue& value = argv[1].refer();
	argv[0] = set >= value;
}

void ClassSet::operator_assign(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	if (ClassSet* otherSet = argv[1])
	{
		const BValueSet& other = otherSet->asset();
		set = other;
	}
}

void ClassSet::operator_bracket(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set(index);
}
void ClassSet::operator_bracket_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set(index);
}

void ClassSet::operator_square_bracket(int argc, BValue* argv)
{
	BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set[index];
}
void ClassSet::operator_square_bracket_const(int argc, BValue* argv)
{
	const BValueSet& set = this->asset();
	int index = argv[1];
	argv[0] = set[index];
}
